﻿// *----------------------------------------------------------------
// Copyright (C) 2017 通通优品
// 版权所有。
// 
// 类名：IEventBus.cs
// 功能描述：TongTongMall
// 
// Create User：jym 2017/02/09
// 
// Edit User：UserName,EditTime
// Describe：Describe
// ----------------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TongTongMall.Events.Handlers;
using TongTongMall.Events.Handlers.Factories;

namespace TongTongMall.Events
{
    public interface IEventBus
    {
        #region Register

          /// <summary>
          /// 注册事件到事件总线
          /// </summary>
          /// <typeparam name="TEventData">事件源参数对象</typeparam>
          /// <param name="action">事件源</param>
          /// <returns></returns>
        IDisposable Register<TEventData>(Action<TEventData> action) where TEventData : IEventData;

        /// <summary>
        /// 注册事件到事件总线
        /// </summary>
        /// <typeparam name="TEventData">事件源参数对象</typeparam>
        /// <param name="handler">包含事件处理的操作工对象（已包含事件中的所需的参数）</param>
        /// <returns></returns>
        IDisposable Register<TEventData>(IEventHandler<TEventData> handler) where TEventData : IEventData;

        /// <summary>
        /// 注册事件到事件总线
        /// </summary>
        /// <typeparam name="TEventData">事件源参数对象</typeparam>
        /// <typeparam name="THandler">操作工对象</typeparam>
        /// <returns></returns>
        IDisposable Register<TEventData, THandler>() where TEventData : IEventData where THandler : IEventHandler<TEventData>, new();

        /// <summary>
        /// 注册事件到事件总线
        /// </summary>
        /// <param name="eventType">事件对象</param>
        /// <param name="handler">操作工对象</param>
        /// <returns></returns>
        IDisposable Register(Type eventType, IEventHandler handler);

        /// <summary>
        /// 注册事件到事件总线
        /// </summary>
        /// <typeparam name="TEventData"></typeparam>
        /// <param name="handlerFactory">事件处理工厂，工厂内自生产操作工处理事件对象</param>
        /// <returns></returns>
        IDisposable Register<TEventData>(IEventHandlerFactory handlerFactory) where TEventData : IEventData;

        /// <summary>
        /// 注册事件到事件总线
        /// </summary>
        /// <param name="eventType">事件类型</param>
        /// <param name="handlerFactory">事件处理工厂，工厂内自生产操作工处理事件对象</param>
        /// <returns></returns>
        IDisposable Register(Type eventType, IEventHandlerFactory handlerFactory);

        #endregion

        #region Unregister

        /// <summary>
        /// 从事件总线内注销某个事件
        /// </summary>
        /// <typeparam name="TEventData"></typeparam>
        /// <param name="action"></param>
        void Unregister<TEventData>(Action<TEventData> action) where TEventData : IEventData;

        /// <summary>
        /// 从事件总线内注销某个事件
        /// </summary>
        /// <typeparam name="TEventData"></typeparam>
        /// <param name="handler"></param>
        void Unregister<TEventData>(IEventHandler<TEventData> handler) where TEventData : IEventData;

        /// <summary>
        /// 从事件总线内注销某个事件
        /// </summary>
        /// <param name="eventType"></param>
        /// <param name="handler"></param>
        void Unregister(Type eventType, IEventHandler handler);

        /// <summary>
        /// 从事件总线内注销某个事件
        /// </summary>
        /// <typeparam name="TEventData"></typeparam>
        /// <param name="factory"></param>
        void Unregister<TEventData>(IEventHandlerFactory factory) where TEventData : IEventData;

        /// <summary>
        /// 从事件总线内注销某个事件
        /// </summary>
        /// <param name="eventType"></param>
        /// <param name="factory"></param>
        void Unregister(Type eventType, IEventHandlerFactory factory);

        /// <summary>
        /// 从事件总线内注销某个事件
        /// </summary>
        /// <typeparam name="TEventData"></typeparam>
        void UnregisterAll<TEventData>() where TEventData : IEventData;

        /// <summary>
        /// 从事件总线内注销某个事件
        /// </summary>
        /// <param name="eventType"></param>
        void UnregisterAll(Type eventType);

        #endregion

        #region Trigger

        /// <summary>
        /// 从事件总线内触发一个领域事件（可能包含多个）
        /// </summary>
        /// <typeparam name="TEventData"></typeparam>
        /// <param name="eventData">事件参数</param>
        void Trigger<TEventData>(TEventData eventData) where TEventData : IEventData;

        /// <summary>
        /// 从事件总线内触发一个指定的领域事件（可能包含多个）
        /// </summary>
        /// <typeparam name="TEventData"></typeparam>
        /// <param name="eventSource">事件</param>
        /// <param name="eventData">事件参数</param>
        void Trigger<TEventData>(object eventSource, TEventData eventData) where TEventData : IEventData;

        /// <summary>
        /// 从事件总线内触发一个指定的领域事件（可能包含多个）
        /// </summary>
        /// <param name="eventType">事件类型</param>
        /// <param name="eventData">事件参数</param>
        void Trigger(Type eventType, IEventData eventData);

        /// <summary>
        /// 从事件总线内触发一个指定的领域事件
        /// </summary>
        /// <param name="eventType">事件类型</param>
        /// <param name="eventSource">事件源</param>
        /// <param name="eventData">事件参数</param>
        void Trigger(Type eventType, object eventSource, IEventData eventData);

        /// <summary>
        /// 从事件总线内触发一个指定的领域事件
        /// </summary>
        /// <typeparam name="TEventData"></typeparam>
        /// <param name="eventData"></param>
        /// <returns></returns>
        Task TriggerAsync<TEventData>(TEventData eventData) where TEventData : IEventData;

        /// <summary>
        /// 从事件总线内触发一个指定的领域事件
        /// </summary>
        /// <typeparam name="TEventData"></typeparam>
        /// <param name="eventSource"></param>
        /// <param name="eventData"></param>
        /// <returns></returns>
        Task TriggerAsync<TEventData>(object eventSource, TEventData eventData) where TEventData : IEventData;

        /// <summary>
        /// 从事件总线内触发一个指定的领域事件
        /// </summary>
        /// <param name="eventType"></param>
        /// <param name="eventData"></param>
        /// <returns></returns>
        Task TriggerAsync(Type eventType, IEventData eventData);

        /// <summary>
        /// 从事件总线内触发一个指定的领域事件
        /// </summary>
        /// <param name="eventType"></param>
        /// <param name="eventSource"></param>
        /// <param name="eventData"></param>
        /// <returns></returns>
        Task TriggerAsync(Type eventType, object eventSource, IEventData eventData);


        #endregion

        /// <summary>
        /// 获取已经注册的事件总线
        /// </summary>
        /// <returns></returns>
        Dictionary<Type, List<IEventHandlerFactory>> GetAllEvents();
    }
}
